﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

namespace rpncs
{
    public partial class MainPage : PhoneApplicationPage
    {
        protected static Calc calc=null;
        
        private Boolean isShifted = false;
        private bool isHyper = false;
        private static Dictionary<String, String> shiftables = new Dictionary<string, string>();
        // Constructor
        public MainPage()
        {
            InitializeComponent();
            calc = new Calc();
            //result.Content = "Calculator in FIFO mode started...";
            //auxPanel.Children.CopyTo( shiftables, 0 );
            shiftables.Add( "y^x", "%" );
            shiftables.Add( "e^x", "10^x" );
            shiftables.Add( "sqrt", "x^2" );
            shiftables.Add( "LN", "LOG" );
            shiftables.Add( "SIN", "ASIN" );
            shiftables.Add( "COS", "ACOS" );
            shiftables.Add( "TAN", "ATAN" );
            shiftables.Add( "1/x", "%CHG" );
            shiftables.Add( "x!", "E" );
        }

        
        private void entry_TextInputStart(object sender, TextCompositionEventArgs e)
        {
            result.Content = "";
        }

        void OnEnterButtonClick(object sender, EventArgs args)
        {
            String value = entryValues.Text.ToString();
            if ( value == null || value.Equals("") )
            {
                value = "0";
            }
            double dValue=0;
            if (value.Contains( "1E?" )) {
                dValue = Math.Pow( 10, Convert.ToDouble( value.Substring( 3 ) ) );
            }
            else {
                dValue = Double.Parse( value );
            }
                
            calc.addToList(value);
            calc.calcStack.Enqueue(dValue);
            entryValues.Text = "";
            result.Content = result.Content + dValue.ToString() + '\n';
            
        }

        void OnShiftKeyPressed(object sender, EventArgs args)
        {
            resultAppend( "shift?" );
        }

        

        private void clear_Click(object sender, RoutedEventArgs e)
        {
            calc.clearAll();
            result.Content = "";
        }

        private void sign_Click(object sender, RoutedEventArgs e)
        {
            Decimal sd = Convert.ToDecimal(entryValues.Text);
            String strVal = Decimal.Negate(sd)+"";
            entryValues.Text = strVal;

            
        }

        private void xExpY_Click(object sender, RoutedEventArgs e)
        {
            if (!isShifted) {
                if (entryValues.Text.Equals( "" )) {
                    calc.xPowerY();
                }
                else {
                    calc.addToStack( entryValues.Text );
                    calc.xPowerY();
                }
            }
            else {
                calc.percentage();
            }

            result.Content = ('\n'+"="+calc.calcStack.Peek());
        }
        private void plus_Click( object sender, EventArgs e ) {
            Double rslt = new Double();
            result.Content += ("+");
            try {
                rslt = calc.doBasicCalcs( Calc.ADD );
            }
            catch (DivideByZeroException de) {
                System.Console.Error.WriteLine( de.Message );
            }

            result.Content += ('\n'+"="+rslt);
            calc.calcStack.Enqueue( rslt );
        }
        private void minus_Click( object sender, RoutedEventArgs e ) {

            calc.calcStack.Enqueue( calc.doBasicCalcs( Calc.SUB ) );
            resultOut();

        }

        private void multiply_Click( object sender, RoutedEventArgs e ) {
            calc.calcStack.Enqueue( calc.doBasicCalcs( Calc.MULT) );
            resultOut();
        }

        private void divide_Click( object sender, RoutedEventArgs e ) {
            calc.calcStack.Enqueue( calc.doBasicCalcs( Calc.DIV ) );
            resultOut();
        }

        private void eExp_Click( object sender, RoutedEventArgs e ) {
            if (!isShifted)
                calc.eToX();
            else
                calc.tenX();

            resultOut();
        }

        private void sqrt_Click( object sender, RoutedEventArgs e ) {
            if (!isShifted) {
                calc.sqrt();
            }
            else {
                calc.xSquared();
            }
            resultOut();
        }

        private void ln_Click( object sender, RoutedEventArgs e ) {
            calc.logarithm( Calc.LN );
            resultOut();
        }

        private void E_Click( object sender, RoutedEventArgs e ) {
            calc.oneOverX();
            
            //calc.calcStack.Enqueue( Math.E );
           resultOut();
        }

        private void pi_Click( object sender, RoutedEventArgs e ) {
            calc.calcStack.Enqueue( Math.PI);
            resultOut();
        }

        private void resultOut() {
            result.Content += ('\n' + "=" + calc.calcStack.Peek());
        }

        private void resultAppend( string str ) {
            result.Content += str;
        }

              
        private void trigButtonClick( int op ) {
            calc.trig( op, isShifted, isHyper );
            resultOut();
        }
        private void shift_Click( object sender, RoutedEventArgs e ) {

            isShifted=shift.IsChecked.GetValueOrDefault( false );

            shiftAll();
        }
        //TODO: clean this shifted logic up
        private void shiftAll() {
            string val="";
            string cntnt = "";
            //this is safe.  they are all buttons
            foreach (Button n in exponentPanel.Children.Cast<Button>()) {
                swapLabels( ref val, ref cntnt, n );
                }
            foreach (Button b in trigPanel.Children.Cast<Button>()) {
                 swapLabels(ref val, ref cntnt,b);
            }
            foreach (Button b in auxPanel.Children.Cast<Button>()) {
                swapLabels( ref val, ref cntnt, b );
            }
            
        }

        private void swapLabels( ref string val, ref string cntnt, Button n ) {
            cntnt = n.Content.ToString();
            if (isShifted) {

                if (shiftables.TryGetValue( cntnt, out val ))
                    n.Content = val;
            }
            else {
                foreach (KeyValuePair<string, string> kvp in shiftables) {
                    if (kvp.Value.Equals( cntnt ))
                        n.Content = kvp.Key;

                }
            }
        }

        private void hyp_Click( object sender, RoutedEventArgs e ) {
            isHyper = !isHyper;
        }

        private void sin_Click( object sender, RoutedEventArgs e ) {
            trigButtonClick( Calc.SIN );
            
        }

        private void cos_Click( object sender, RoutedEventArgs e ) {
            trigButtonClick( Calc.COS );
        }

        private void tan_Click( object sender, RoutedEventArgs e ) {
            trigButtonClick( Calc.TAN );
        }

        private void E_Click_1( object sender, RoutedEventArgs e ) {

        }

        private void factorial_Click( object sender, RoutedEventArgs e ) {
            if (!isShifted) {
                calc.factorial();
                resultOut();
            }
            else {
                result.Content=calc.Exp();
            }
        }

        private void switchVars_Click( object sender, RoutedEventArgs e ) {
            calc.calcStack.Reverse<double>();
        }
    }
}